//
//  SENavigationController.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/2.
//

import UIKit

class SENavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        UINavigationBar.appearance().titleTextAttributes =
            [NSAttributedString.Key.font: UIFont.medium(18),
             NSAttributedString.Key.foregroundColor: UIColor.darkText]
        UINavigationBar.appearance().tintColor = UIColor.darkText

        guard let interactionGesture = interactivePopGestureRecognizer,
              let targetView = interactionGesture.view,
              let internalTargets = interactionGesture.value(forKeyPath: "targets") as? [NSObject],
              let internalTarget = internalTargets.first?.value(forKey: "target") else { return }
        
        let action = Selector(("handleNavigationTransition:"))
        
        let fullScreenGesture = UIPanGestureRecognizer(target: internalTarget, action: action)
        fullScreenGesture.delegate = self
        targetView.addGestureRecognizer(fullScreenGesture)
        interactionGesture.isEnabled = false
    }
    
    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        if viewControllers.count > 0 { viewController.hidesBottomBarWhenPushed = true }
        super.pushViewController(viewController, animated: animated)
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        guard let topVc = topViewController else { return .lightContent }
        return topVc.preferredStatusBarStyle
    }
}

// MARK: - UIGestureRecognizerDelegate

extension SENavigationController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let isLeftToRight = UIApplication.shared.userInterfaceLayoutDirection == .leftToRight
        guard let gesture = gestureRecognizer as? UIPanGestureRecognizer else { return true }
        if gesture.translation(in: gestureRecognizer.view).x * (isLeftToRight ? 1 : -1) <= 0 || disablePopGesture {
            return false
        }
        return viewControllers.count != 1
    }
}

enum SENavigationBarStyle {
    case theme(color: UIColor = Asset.main.color), clear, white
    
    var titleTextAttributes: [NSAttributedString.Key: Any] {
        switch self {
        case .theme:
            return [
                NSAttributedString.Key.font: UIFont.medium(18),
                NSAttributedString.Key.foregroundColor: Asset.white.color
            ]
        case .clear, .white:
            return [
                NSAttributedString.Key.font: UIFont.medium(18),
                NSAttributedString.Key.foregroundColor: Asset.textDark.color
            ]
        }
    }
    
    var tintColor: UIColor? {
        switch self {
        case .theme: return Asset.white.color
        case .clear,
             .white: return Asset.textDark.color
        }
    }
    
    var backgroundImage: UIImage {
        switch self {
        case .theme(let color): return color.image()
        case .clear: return UIImage()
        case .white: return Asset.white.color.image()
        }
    }
    
    var barStyle: UIBarStyle {
        switch self {
        case .theme: return .black
        case .clear, .white: return .default
        }
    }
}

extension UINavigationController {
    private struct AssociatedKeys {
        static var disablePopGesture: Void?
    }
    
    var disablePopGesture: Bool {
        get {
            objc_getAssociatedObject(self, &AssociatedKeys.disablePopGesture) as? Bool ?? false
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.disablePopGesture, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    func navBarStyle(_ style: SENavigationBarStyle, isTranslucent: Bool = true) {
        navigationBar.isTranslucent = isTranslucent
        navigationBar.barStyle = style.barStyle
        navigationBar.setBackgroundImage(style.backgroundImage, for: .default)
        navigationBar.shadowImage = UIImage()
        navigationBar.tintColor = style.tintColor
        navigationBar.titleTextAttributes = style.titleTextAttributes
    }
}
